﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Data;
using System.Transactions;

namespace ATM
{
    class Program
    {
        static void Main(string[] args)
        {
            Withdraw("fde3bb4651", "3453",100);
        }

        static void Withdraw(string cardNum, string cardPin,decimal sum)
        {
            SqlConnection dbCon = new SqlConnection(Settings1.Default.ATMCon);
            dbCon.Open();
            using (dbCon)
            {
                using (SqlTransaction trans = dbCon.BeginTransaction())
                {

                    try
                    {
                        SqlCommand cmd = new SqlCommand("select * from CardAccounts where CardNumber='" + cardNum + "'", dbCon);
                        cmd = dbCon.CreateCommand();
                        cmd.Transaction = trans;
                        cmd.CommandText = "select * from CardAccounts where CardNumber='" + cardNum + "'";
                        SqlDataReader reader = cmd.ExecuteReader();
                        using (reader)
                        {
                            if (reader.Read() == false)
                            {
                                throw new ArgumentException("Unexisting card number!");

                            }

                        }
                        // SqlTransaction trans = dbCon.BeginTransaction(IsolationLevel.ReadCommitted);
                        SqlCommand cmdPIN = new SqlCommand("select * from CardAccounts where cardPin='" + cardPin + "'", dbCon);
                        cmdPIN = dbCon.CreateCommand();
                        cmdPIN.Transaction = trans;
                        cmdPIN.CommandText = "select * from CardAccounts where cardPin='" + cardPin + "'";
                        SqlDataReader readerPIN = cmdPIN.ExecuteReader();
                        using (readerPIN)
                        {
                            if (readerPIN.Read() == false)
                            {
                                throw new ArgumentException("Wrong card PIN!");
                            }
                        }


                        SqlCommand cmdUpdate = new SqlCommand("update CardAccounts set CardCash=CardCash-" + sum + " where CardNumber='" + cardNum + "' and cardPin='" + cardPin + "'", dbCon);
                        cmdUpdate = dbCon.CreateCommand();
                        cmdUpdate.Transaction = trans;
                        cmdUpdate.CommandText = "update CardAccounts set CardCash=CardCash-" + sum + " where CardNumber='" + cardNum + "' and cardPin='" + cardPin + "'";
                        cmdUpdate.ExecuteNonQuery();
                        

                        SqlCommand cmdCheck = new SqlCommand("select CardCash from CardAccounts where CardNumber='" + cardNum + "' and cardPin='" + cardPin + "'", dbCon);
                        cmdCheck = dbCon.CreateCommand();
                        cmdCheck.Transaction = trans;
                        cmdCheck.CommandText = "select CardCash from CardAccounts where CardNumber='" + cardNum + "' and cardPin='" + cardPin + "'";
                        SqlDataReader readerCheck = cmdCheck.ExecuteReader();
                        using (readerCheck)
                        {
                            readerCheck.Read();
                            decimal newSum = (decimal)readerCheck["CardCash"];
                            if (newSum <0)
                            {
                                throw new ArgumentException("Unsufficient funds!");
                            }
                        }
                        Console.WriteLine("The sum is withdrawed successfully");
                        trans.Commit();
                        
                    }

                    catch (ArgumentException e)
                    {
                        Console.WriteLine("Transaction cancelled.");
                        Console.WriteLine(e.Message);
                        trans.Rollback();
                    }

                }
            }


        }
    }
}
